#include "../mqserver/virtualhost.hpp"
#include <gtest/gtest.h>

MyRabbitMQ::VirtualHost::ptr hosts;

class VirtualHostTest : public testing::Environment
{
public:
    // 初始化
    virtual void SetUp() override
    {
        std::string basedir = "./";

        hosts = std::make_shared<MyRabbitMQ::VirtualHost>("host-1","./data.db",basedir);
    }

    virtual void TearDown() override
    {
        // 清理队列操作
        // msgQueues->clear();
        std::cout << "执行真正数据库清理操作" << std::endl;
    }
};
// //声明测试
// TEST(VirtualHostTest, insert_test)
// {

//     //交换机
//     google::protobuf::Map<std::string,std::string> map1;
//     google::protobuf::Map<std::string,std::string> map2; map2.insert({"man!","what can i say?"});
//     google::protobuf::Map<std::string,std::string> map3; map3.insert({"manba","out"});
//     google::protobuf::Map<std::string,std::string> map4; map4.insert({"a~","xi ba..."});

//     hosts->declareExchange("exchange-1",protoMQ::ExchangeType::fanout,true,true,map1);
//     hosts->declareExchange("exchange-2",protoMQ::ExchangeType::fanout,true,true,map2);
//     hosts->declareExchange("exchange-3",protoMQ::ExchangeType::fanout,true,true,map3);
//     hosts->declareExchange("exchange-4",protoMQ::ExchangeType::fanout,true,true,map4);
//     hosts->declareExchange("exchange-5",protoMQ::ExchangeType::fanout,true,true,map1);

//     //队列
     
//     hosts->declareMsgQueue("queue-1",true,true,true,google::protobuf::Map<std::string,std::string>());
//     hosts->declareMsgQueue("queue-3",true,true,true,google::protobuf::Map<std::string,std::string>());
//     hosts->declareMsgQueue("queue-5",true,true,true,google::protobuf::Map<std::string,std::string>());
//     hosts->declareMsgQueue("queue-7",true,true,true,google::protobuf::Map<std::string,std::string>());
//     hosts->declareMsgQueue("queue-9",true,true,true,google::protobuf::Map<std::string,std::string>());

//     //绑定
//     hosts->Bind("exchange-1","queue-1","bindingkey-1",true);
//     hosts->Bind("exchange-1","queue-3","bindingkey-2",true);
//     hosts->Bind("exchange-1","queue-5","bindingkey-3",true);
    
//     hosts->Bind("exchange-2","queue-7","bindingkey-4",true);
//     hosts->Bind("exchange-1","queue-9","bindingkey-5",true);
    
//     hosts->Bind("exchange-1","queue-1","bindingkey-6",true);
//     hosts->Bind("exchange-2","queue-1","bindingkey-7",true);
//     hosts->Bind("exchange-3","queue-1","bindingkey-8",true);
    
//     hosts->Bind("exchange-4","queue-1","bindingkey-9",true);
//     hosts->Bind("exchange-4","queue-3","bindingkey-10",true);
//     hosts->Bind("exchange-4","queue-5","bindingkey-11",true);
//     hosts->Bind("exchange-4","queue-7","bindingkey-12",true);
//     hosts->Bind("exchange-4","queue-9","bindingkey-13",true);
    
//     hosts->Bind("exchange-5","queue-1","bindingkey-14",true);
//     hosts->Bind("exchange-5","queue-3","bindingkey-15",true);
//     hosts->Bind("exchange-5","queue-5","bindingkey-16",true);

//     hosts->Bind("exchange-5","queue-7","bindingkey-17",false);
//     hosts->Bind("exchange-5","queue-9","bindingkey-18",false);

// }

// // 删除测试
// TEST(VirtualHostTest, delete_test)
// {
//     //删除特定绑定
//     hosts->unBind("exchange-5","queue-7");
//     hosts->unBind("exchange-5","queue-8");
//     hosts->unBind("exchange-5","queue-9");

//     //删除特定交换机以及其绑定信息
//     hosts->deleteExchange("exchange-1");

//     //删除特定队列以及其绑定信息
//     hosts->deleteMsgQueue("queue-1");
// }

// // 获取指定与获取全部测试
// TEST(VirtualHostTest, get_test)
// {
//     //获取所有交换机及其绑定信息
//     auto exchanges = hosts->selectExchange();
//     for(auto& f :exchanges)
//     {
//         LOG(logLevel::normal) << f.first << std::endl;

//         auto bindings = hosts->selectBindings(f.first);

//         for(auto& bind : bindings)
//         {
//             LOG(logLevel::normal) << "交换机 " << f.first << "对应绑定信息 " << bind.first << std::endl;
//         }   
//     }

//     LOG(logLevel::normal) << "------------------" << std::endl;

//     //获取所有队列
//     auto queues = hosts->selectMsgQueue();
//     for(auto& f :queues)
//     {
//         LOG(logLevel::normal) << f.first << std::endl;
//     }
//     LOG(logLevel::normal) << "------------------" << std::endl;

// }

//消息测试
TEST(VirtualHostTest,message_test)
{
    protoMQ::BaseProperties base1;
    protoMQ::BaseProperties base2;
    protoMQ::BaseProperties base3;
    protoMQ::BaseProperties base4;
    protoMQ::BaseProperties base5;

    base1.set_id("base1");
    base2.set_id("base2");
    base3.set_id("base3");
    base4.set_id("base4");
    base5.set_id("base5");

    base1.set_mode(protoMQ::DeliveryMode::durable);
    base2.set_mode(protoMQ::DeliveryMode::undurable);
    base3.set_mode(protoMQ::DeliveryMode::durable);
    base4.set_mode(protoMQ::DeliveryMode::durable);
    base5.set_mode(protoMQ::DeliveryMode::durable);

    base1.set_routing_key(".base1.");
    base2.set_routing_key(".base2.");
    base3.set_routing_key(".base3.");
    base4.set_routing_key(".base4.");
    base5.set_routing_key(".base5.");
    
    // hosts->basePublish("queue-5",&base1,"这是测试消息一,消息id为base1 应当属于队列五, 应当被持久化--|0|0|0",true);
    // hosts->basePublish("queue-5",&base3,"这是测试消息二,消息id为base3 应当属于队列五, 应当被持久化--|0|0|0",true);
    // hosts->basePublish("queue-5",&base4,"这是测试消息三,消息id为base4 应当属于队列五, 不应当被持久化--|0|0|0",false);
    // hosts->basePublish("queue-5",&base5,"这是测试消息四,消息id为base5 应当属于队列五, 不应当被持久化--|0|0|0",false);
    // hosts->basePublish("queue-5",&base2,"这是测试消息五,消息id为base2 应当属于队列五, 不应当被持久化--|0|0|0",true);

    //恢复消息, 并进行获取确认
    auto ptr = hosts->basicConsume("queue-5");

    if(ptr != pbMessagePtr())
    {
        LOG(logLevel::DEBUG) << ptr.get()->payload().data() << std::endl;
        LOG(logLevel::DEBUG) << ptr.get()->payload().isvaild() << std::endl;
        LOG(logLevel::DEBUG) << ptr.get()->payload().properties().id() << std::endl;
        LOG(logLevel::DEBUG) << ptr.get()->payload().properties().routing_key() << std::endl;
        LOG(logLevel::DEBUG) << ptr.get()->payload().properties().mode() << std::endl;
        
        hosts->basicAck("queue-5",ptr.get()->payload().properties().id());
    }
    else
    {
        LOG(logLevel::DEBUG) << "队列没有消息可供获取!" << std::endl;
    }
}

int main(int argc, char *argv[])
{
    testing::InitGoogleTest(&argc, argv);
    testing::AddGlobalTestEnvironment(new VirtualHostTest);
    int ret = RUN_ALL_TESTS();
    return 0;
}